package com.ruifu.worksheet.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.fhzncloud.cloud.common.security.service.CloudUser;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.ruifu.common.feign.RemoteDocService;
import com.ruifu.common.utils.BeanConverter;
import com.ruifu.common.vo.PageResultVO;
import com.ruifu.common.vo.worksheet.WsCommonSheet;
import com.ruifu.worksheet.dto.WsCommonAttachFileDTO;
import com.ruifu.worksheet.dto.WsCommonRelationSheetDTO;
import com.ruifu.worksheet.dto.WsCommonSheetDTO;
import com.ruifu.worksheet.dto.WsCustomizeTypeDTO;
import com.ruifu.worksheet.mapper.WsCommonSheetMapper;
import com.ruifu.worksheet.mapper.WsEcnSheetMapper;
import com.ruifu.worksheet.mapper.WsEcrSheetMapper;
import com.ruifu.worksheet.mapper.WsProblemSheetMapper;
import com.ruifu.worksheet.service.WsCommonSheetService;
import com.ruifu.worksheet.util.AuthorityUtil;
import com.ruifu.worksheet.util.EnumUtil;
import com.ruifu.worksheet.util.SpringUtil;
import com.ruifu.worksheet.vo.WsCommonRelationSheetVO;
import com.ruifu.worksheet.vo.WsCommonSheetVO;
import com.ruifu.worksheet.vo.WsCustomizeTypeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

/**
 * @author yuanyundi
 * @date 2020/04/20
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class WsCommonSheetServiceImpl implements WsCommonSheetService {
    /**
     * 注入工作单Mapper接口
     */
    @Autowired(required = false)
    private WsProblemSheetMapper wsProblemSheetMapper;
    @Autowired(required = false)
    private WsEcrSheetMapper wsEcrSheetMapper;
    @Autowired(required = false)
    private WsEcnSheetMapper wsEcnSheetMapper;

    @Autowired
    private RemoteDocService remoteDocService;

    /**
     * 注入通用代码Mapper接口
     */
    @Autowired(required = false)
    private WsCommonSheetMapper wsCommonSheetMapper;

    /**
     * 注入DTO
     */
    @Autowired(required = false)
    private WsCustomizeTypeDTO wsCustomizeTypeDTO;
    @Autowired(required = false)
    private WsCommonSheetDTO wsCommonSheetDTO;
    @Autowired(required = false)
    private WsCommonRelationSheetDTO wsCommonRelationSheetDTO;

    /**
     * 变更单类型列表条件查询
     *
     * @param pageNum         当前页
     * @param pageSize        显示条数
     * @param classFlag       查询类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @param wsCommonSheetVO 查询条件
     * @param cloudUser       登陆人员信息
     * @return PageResultVO 查询数据集合
     */
    @Override
    public PageResultVO findPage(int pageNum, int pageSize, int classFlag, WsCommonSheetVO wsCommonSheetVO, CloudUser cloudUser) {
        //开启分页组件
        PageHelper.startPage(pageNum, pageSize);
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        //查询分页对象
        Page<WsCommonSheetDTO> page = (Page<WsCommonSheetDTO>) wsCommonSheetMapper.findAll(wsCommonSheetVO, cloudUser);
        //循环查询工作单权限码
        for(WsCommonSheetDTO wsCommonSheetDTO:page){
            //查询流程权限码
            WsCommonSheet wsCommonSheet = BeanConverter.copyProperties(wsCommonSheetDTO,WsCommonSheet.class);
            wsCommonSheet.setCmWsClassFlag(String.valueOf(classFlag));
            String flowAuthorCode = remoteDocService.feignWorkFormPermissions(wsCommonSheet);
            //查询工作单权限码
            String authorityCode = new AuthorityUtil().getWsAuthorCode(wsCommonSheetDTO,cloudUser,flowAuthorCode);
            wsCommonSheetDTO.setAuthorityCode(authorityCode);
        }
        /*DTO转VO*/
        List<WsCommonSheetVO> wsCommonSheetVOList = BeanConverter.copyList(page.getResult(), WsCommonSheetVO.class);
        //返回分页结果
        return new PageResultVO(page.getTotal(), wsCommonSheetVOList);
    }

    /**
     * 变更单类型查询
     *
     * @param typeName  工作单类型Name
     * @param classFlag 查询类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @return WsCustomizeTypeDTO 变更单类型DTO
     */
    @Override
    public WsCustomizeTypeVO findType(String typeName, int classFlag,CloudUser cloudUser) {
        //根据typeId查询变更类型数据
        wsCustomizeTypeDTO = wsCommonSheetMapper.findByName(typeName, classFlag, cloudUser);
        /*dto转vo*/
        return BeanConverter.copyProperties(wsCustomizeTypeDTO, WsCustomizeTypeVO.class);
    }

    /**
     * 工作单新增
     *
     * @param classFlag       查询类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @param wsCommonSheetVO 工作单提交数据hu
     * @param cloudUser       用户登录信息
     */
    @Override
    public void insertEntity(int classFlag, WsCommonSheetVO wsCommonSheetVO, CloudUser cloudUser) {
        wsCommonSheetDTO = BeanConverter.copyProperties(wsCommonSheetVO, WsCommonSheetDTO.class);
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        //插入问题报告单表
        wsCommonSheetMapper.insertWorkSheet(wsCommonSheetDTO, cloudUser);
        //根据工作单编号查询插入工作单ID
        BigInteger wsId = wsCommonSheetDTO.getCmId();
        if (StringUtil.isNotEmpty(wsCommonSheetDTO.getCmAttachFileVOList())) {
            //Json字符串转集合
            List<WsCommonAttachFileDTO> wsCommonAttachFileDTOList = JSONArray.parseArray(wsCommonSheetDTO.getCmAttachFileVOList(), WsCommonAttachFileDTO.class);
            //插入问题报告单附件表
            insertWsFile(wsCommonAttachFileDTOList, wsId, classFlag, cloudUser);
        }
    }

    /**
     * 获取工作单类型下拉集合
     *
     * @param classFlag 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @param cloudUser 用户登陆人员信息
     * @return String  下拉集合字符串，逗号分隔
     */
    @Override
    public String findTypeNamesByClass(int classFlag, CloudUser cloudUser) {
        return wsCommonSheetMapper.findTypeNameSelect(classFlag, cloudUser);
    }

    /**
     * 工作单单一查询
     *
     * @param cmId      工作单主键
     * @param classFlag 查询类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @return WsCommonSheetVO 通用工作单VO
     */
    @Override
    public WsCommonSheetVO findWorkSheetById(BigInteger cmId, int classFlag,CloudUser cloudUser) {
        List<WsCommonAttachFileDTO> wsCommonAttachFileDTOList = new ArrayList<>();
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        //根据id查询问题报告单数据
        wsCommonSheetDTO = wsCommonSheetMapper.findWorkSheetById(cmId);
        //查询流程权限码
        WsCommonSheet wsCommonSheet = BeanConverter.copyProperties(wsCommonSheetDTO,WsCommonSheet.class);
        wsCommonSheet.setCmWsClassFlag(String.valueOf(classFlag));
        String flowAuthorCode = remoteDocService.feignWorkFormPermissions(wsCommonSheet);
        //设置权限码
        wsCommonSheetDTO.setAuthorityCode(new AuthorityUtil().getWsAuthorCode(wsCommonSheetDTO,cloudUser,flowAuthorCode));
        //根据id查询问题报告单附件数据
        wsCommonAttachFileDTOList = wsCommonSheetMapper.findAttachFile(cmId);
        //集合转Json字符串,填充属性
        if (wsCommonAttachFileDTOList.size() != 0) {
            wsCommonSheetDTO.setCmAttachFileVOList(JSONArray.toJSONString(wsCommonAttachFileDTOList));
        }
        /*dto转vo*/
        return BeanConverter.copyProperties(wsCommonSheetDTO, WsCommonSheetVO.class);
    }

    /**
     * 附件表新增
     *
     * @param wsCommonAttachFileDTOList 附件表数据集合
     * @param wsId                      关联工作单ID
     * @param classFlag                 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @param cloudUser                 登陆人员信息
     */
    public void insertWsFile(List<WsCommonAttachFileDTO> wsCommonAttachFileDTOList, BigInteger wsId, int classFlag, CloudUser cloudUser) {
        //遍历问题对象
        for (WsCommonAttachFileDTO wsCommonAttachFileDTO : wsCommonAttachFileDTOList) {
            //设置关联工作单ID
            wsCommonAttachFileDTO.setCmSheetId(wsId);
            //获取工作单通用Mapper
            WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
            //存储数据
            wsCommonSheetMapper.insertAttachFile(wsCommonAttachFileDTO, cloudUser);
        }
    }

    /**
     * 工作单编辑提交
     *
     * @param wsCommonSheetVO 工作单数据实体
     * @param classFlag       类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     */
    @Override
    public void updateEntity(WsCommonSheetVO wsCommonSheetVO, int classFlag, CloudUser cloudUser) {
        /*VO转DTO*/
        wsCommonSheetDTO = BeanConverter.copyProperties(wsCommonSheetVO, WsCommonSheetDTO.class);
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        //修改问题报告单数据库
        wsCommonSheetMapper.updateWorkSheet(wsCommonSheetDTO, cloudUser);
        //根据工作单ID，作废附件表数据
        wsCommonSheetMapper.cancelAttarchFile(wsCommonSheetDTO.getCmId());
        //新增附件表数据
        if (StringUtil.isNotEmpty(wsCommonSheetDTO.getCmAttachFileVOList())) {
            insertWsFile(JSONArray.parseArray(wsCommonSheetDTO.getCmAttachFileVOList(), WsCommonAttachFileDTO.class), wsCommonSheetDTO.getCmId(), classFlag, cloudUser);
        }
    }

    /**
     * 工作单数据作废
     *
     * @param cmId      工作单主键
     * @param classFlag 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     */
    @Override
    public void deleteEntity(BigInteger cmId, int classFlag) {
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        //作废工作单
        wsCommonSheetMapper.cancelWorkSheet(cmId);
        //作废工作单附件
        wsCommonSheetMapper.cancelAttarchFile(cmId);

    }

    /**
     * 关联变更单新增
     *
     * @param cmId                         工作单主键
     * @param wsCommonRelationSheetDTOList 关联变更单集合
     * @param cloudUser                    用户登录人员信息
     */
    @Override
    public void saveRelatedSheet(BigInteger cmId, List<WsCommonRelationSheetDTO> wsCommonRelationSheetDTOList, CloudUser cloudUser) {
        //根据主变更单cmId清空关联变更单
        wsCommonSheetMapper.delRelateSheetByMainId(cmId, cloudUser);
        //遍历集合
        for (WsCommonRelationSheetDTO wsCommonRelationSheetDTO : wsCommonRelationSheetDTOList) {
            wsCommonSheetMapper.saveRelatedSheet(wsCommonRelationSheetDTO, cloudUser);
        }
    }

    /**
     * 关联变更单查询
     *
     * @param cmId      工作单主键
     * @param cloudUser 用户登录人员信息
     * @return List<WsCommonRelationSheetVO> 关联变更单数据集合
     */
    @Override
    public List<WsCommonRelationSheetVO> findRelatedSheet(BigInteger cmId, CloudUser cloudUser) {
        List<WsCommonRelationSheetDTO> wsCommonRelationSheetDTOList = wsCommonSheetMapper.findRelatedSheet(cmId, cloudUser);
        return BeanConverter.copyList(wsCommonRelationSheetDTOList, WsCommonRelationSheetVO.class);
    }

    /**
     * 获取WsCommonSheetMapper对象
     *
     * @param classFlag 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @return WsCommonSheetMapper 返回WsCommonSheetMapper对象
     */
    public WsCommonSheetMapper retWsCommonSheetMapper(int classFlag) {
        //获取枚举值:className;
        String className = EnumUtil.valueOf("WS_" + classFlag).getClassName();
        //根据BeanName找到对应的Mapper,运用多态转换为父类
        WsCommonSheetMapper wsCommonSheetMapper = (WsCommonSheetMapper) SpringUtil.getBean(className);
        return wsCommonSheetMapper;
    }

    /**
     * 工作单编号同账套唯一校验
     *
     * @param classFlag 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @param wsCode    工作单编号
     * @param cloudUser 登录人员信息
     * @return int 查询条数
     */
    @Override
    public int checkWsCode(String wsCode, int classFlag, CloudUser cloudUser) {
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        return wsCommonSheetMapper.countRow(wsCode, cloudUser);
    }

    /**
     * 查询变更单关联的流程ID
     *
     * @param cmId      工作单ID
     * @param classFlag 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @param String    工作流模板ID
     */
    @Override
    public String selectFlowIdByWsId(BigInteger cmId, int classFlag) {
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        return wsCommonSheetMapper.selectFlowIdByWsId(cmId);
    }

    /**
     * 修改工作单状态
     *
     * @param cmId 工作单ID
     * @param classFlag 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @param statusVal 状态值
     */
    @Override
    public void updateStatusById(BigInteger cmId, int classFlag, String statusVal) {
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        wsCommonSheetMapper.updateStatusById(cmId,statusVal);
    }

    /**
     * 查询关联问题对象ID集合
     *
     * @parame cmId 工作单ID
     * @param classFlag 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     * @return List<BigInteger> 问题对象ID集合
     */
    @Override
    public String findAttAchFileIDS(BigInteger cmID, int classFlag) {
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        return wsCommonSheetMapper.findAttAchFileIDS(cmID);
    }

    /**
     * 同步修改问题对象状态
     *
     * @param cmId 工作单ID
     * @classFlag 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     */
    @Override
    public void updateAttachFileStatus(BigInteger cmId,int classFlag) {
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        wsCommonSheetMapper.updateAttachFileStatus(cmId);
    }

    /**
     * 账套号数据同步
     *
     * @param sourceSetId  源
     * @param targetSetId  目标
     * @classFlag 类别 0-问题报告单 1-变更申请单 2-变更通知单 3-作废通知单
     */
    @Override
    public void copyWsCommonSheetList(Long sourceSetId, Long targetSetId, int classFlag) {
        //获取工作单通用Mapper
        WsCommonSheetMapper wsCommonSheetMapper = retWsCommonSheetMapper(classFlag);
        List<WsCommonSheetDTO> wsCommonSheetDTOList =  wsCommonSheetMapper.selectListBySetId(sourceSetId);
        for(WsCommonSheetDTO wsCommonSheetDTO:wsCommonSheetDTOList){
            wsCommonSheetDTO.setCmId(null);
            wsCommonSheetDTO.setSetSid(targetSetId);
            wsCommonSheetMapper.insertWsDTO(wsCommonSheetDTO);
        }
    }
}
